package com.linksfield.topup.service.impl;

import com.alibaba.fastjson.JSON;
import com.linksfield.topup.config.dto.CalculateResultParamVo;
import com.linksfield.topup.config.dto.ResultDataDto;
import com.linksfield.topup.config.dto.StringOutputConstant;
import com.linksfield.topup.entity.common.PartnerServicePlan;
import com.linksfield.topup.entity.common.PartnerServicePlanSpecPrice;
import com.linksfield.topup.entity.interfaces.anoverview.admin.fixeddata.request.RequestAdminFixedData;
import com.linksfield.topup.entity.interfaces.anoverview.admin.fixeddata.response.ResponseAdminFixedData;
import com.linksfield.topup.entity.interfaces.anoverview.admin.orderdata.monthdata.request.RequestAdminMonthOrder;
import com.linksfield.topup.entity.interfaces.anoverview.admin.orderdata.monthdata.response.ResponseAdminMonthOrder;
import com.linksfield.topup.entity.interfaces.anoverview.admin.orderdata.yeardata.request.RequestAdminYearOrder;
import com.linksfield.topup.entity.interfaces.anoverview.admin.orderdata.yeardata.response.ResponseAdminYearOrder;
import com.linksfield.topup.entity.interfaces.anoverview.admin.periodcount.ask.request.RequestAskOrderCount;
import com.linksfield.topup.entity.interfaces.anoverview.admin.periodcount.ask.response.ResponseAskOrderCount;
import com.linksfield.topup.entity.interfaces.anoverview.admin.periodcount.defaultask.request.RequestDefaultOrderCount;
import com.linksfield.topup.entity.interfaces.anoverview.admin.periodcount.defaultask.response.PartnerServicePlanList;
import com.linksfield.topup.entity.interfaces.anoverview.admin.periodcount.defaultask.response.ResponseDefaultOrderCount;
import com.linksfield.topup.entity.interfaces.anoverview.admin.periodmoney.request.RequestAskOrderMoney;
import com.linksfield.topup.entity.interfaces.anoverview.admin.periodmoney.response.ResponseAskOrderMoney;
import com.linksfield.topup.entity.interfaces.anoverview.admin.salesrank.request.RequestAdminSalesRank;
import com.linksfield.topup.entity.interfaces.anoverview.admin.salesrank.response.ResponseAdminSalesRank;
import com.linksfield.topup.entity.interfaces.anoverview.partner.orderlinechart.request.RequestOrderLineChart;
import com.linksfield.topup.entity.interfaces.anoverview.partner.orderlinechart.response.ResponseOrderLineChart;
import com.linksfield.topup.entity.interfaces.anoverview.partner.orderpastdata.request.RequestOrderPastData;
import com.linksfield.topup.entity.interfaces.anoverview.partner.orderpastdata.response.ResponseOrderPastData;
import com.linksfield.topup.entity.interfaces.anoverview.partner.orderviewdata.request.RequestOrderViewData;
import com.linksfield.topup.entity.interfaces.anoverview.partner.orderviewdata.response.ResponseOrderViewData;
import com.linksfield.topup.entity.interfaces.anoverview.partner.salesrank.request.RequestSalesRank;
import com.linksfield.topup.entity.interfaces.anoverview.partner.salesrank.response.ResponseSalesRank;
import com.linksfield.topup.entity.interfaces.anoverview.partner.serviceview.request.RequestServiceView;
import com.linksfield.topup.entity.interfaces.anoverview.partner.serviceview.response.ResponseServiceView;
import com.linksfield.topup.entity.interfaces.common.ContentLineChart;
import com.linksfield.topup.entity.interfaces.planmanage.search.request.RequestServicePlanSearch;
import com.linksfield.topup.mapper.OverviewMapper;
import com.linksfield.topup.mapper.ServicePlanMapper;
import com.linksfield.topup.service.OverviewService;
import com.linksfield.topup.utils.TimeFormatOutputUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("viewService")
@Transactional(rollbackFor = Exception.class)

/**
 * 概览：：：业务逻辑处理实现类
 *
 * @author: lm
 * @date: 2019-12-09 15:40
 */
@Slf4j
public class OverviewServiceImpl implements OverviewService {
    @Autowired
    CommonUtilsServiceImpl utilsService;
    @Resource
    private ServicePlanMapper planMapper;
    @Resource
    private OverviewMapper viewMapper;
    @Autowired
    TimeFormatOutputUtil timeUtil;

    /***
     *普通企业：套餐总览
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto partnerServiceView(RequestServiceView request, String token) {

        //1,先去公共服务类验证token
        String results = utilsService.checkPartner(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) && StringUtils.isNotBlank(request.getPartnerCode())) {

                //calculate这个方法需要使用RequestServicePlanSearch这个类有很多的参数，所以这边把partnerCode加到对象中去。
                RequestServicePlanSearch re = new RequestServicePlanSearch();
                re.setPartnerCode(request.getPartnerCode());
                //1,计算套餐总数个数，已上架个数，未上架个数
                List<CalculateResultParamVo> countList = planMapper.calculate(re);

                Map<String, Integer> map = new HashMap<>();
                for (CalculateResultParamVo vo : countList) {
                    map.put(vo.getServicePlanStatus(), vo.getCounts());
                }

                Integer key1 = 0;
                Integer key2 = 0;
                Integer key3 = 0;

                for (String key : map.keySet()) {
                    if ("2".equals(key)) {
                        key2 = map.get(key);
                    }
                    if ("3".equals(key)) {
                        key3 = map.get(key);
                    }
                    if ("1".equals(key)) {
                        key1 = map.get(key);
                    }
                }
                ResponseServiceView count = new ResponseServiceView();
                count.setTotalCount(key1 + key2 + key3);
                count.setBeenOnCount(key2);
                count.setNotOnCount(key1 + key3);

                log.info("【概览】套餐总览返回：" + JSON.toJSONString(count));

                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(count);

            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 普通企业：订单总览，固定数据
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto partnerOrderViewData(RequestOrderViewData request, String token) {

        //1,先去公共服务类验证token
        String results = utilsService.checkPartner(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) && StringUtils.isNotBlank(request.getPartnerCode())) {

                //订单总览：年度订单数，年度订单总额；本月订单数，本月订单总额；上月订单数，上月订单总额：
                String currentYear = timeUtil.currentYear();
                String currentMonth = timeUtil.currentMonth();
                String lastMonth = timeUtil.lastMonth();

                ResponseOrderViewData response = new ResponseOrderViewData();

                //1，全年的订单数量，订单总金额；
                List<CalculateResultParamVo> yearOrderList = viewMapper.withYearData(request.getPartnerCode(), currentYear);
                //处理并返回：全年的订单数量，订单总金额
                CalculateResultParamVo vo = utilsService.convertListToObject(yearOrderList);
                if (null != vo) {
                    response.setCurYearCount(String.valueOf(vo.getOrderCount()));
                    response.setCurYearMoney(String.valueOf(vo.getOrderMoney()));
                } else {
                    response.setCurYearCount("0");
                    response.setCurYearMoney("0");
                }


                //2,先查本月的订单条数，本月订单总金额
                List<CalculateResultParamVo> curMonthOrderList = viewMapper.withMonthData(request.getPartnerCode(), currentMonth);
                //处理并返回：本月的订单数量，订单总金额
                CalculateResultParamVo vo1 = utilsService.convertListToObject(curMonthOrderList);
                if (null != vo1) {
                    response.setCurMonthCount(String.valueOf(vo1.getOrderCount()));
                    response.setCurMonthMoney(String.valueOf(vo1.getOrderMoney()));
                } else {
                    response.setCurMonthCount("0");
                    response.setCurMonthMoney("0");
                }


                //3,再查上月的订单条数，上月订单总金额
                List<CalculateResultParamVo> lastMonthOrderList = viewMapper.withMonthData(request.getPartnerCode(), lastMonth);
                //处理并返回：本月的订单数量，订单总金额
                CalculateResultParamVo vo2 = utilsService.convertListToObject(lastMonthOrderList);
                if (null != vo2) {
                    response.setLastMonthCount(String.valueOf(vo2.getOrderCount()));
                    response.setLastMonthMoney(String.valueOf(vo2.getOrderMoney()));
                } else {
                    response.setLastMonthCount("0");
                    response.setLastMonthMoney("0");
                }


                log.info("【概览】订单总览数据返回：" + JSON.toJSONString(response));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(response);
            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 概览：普通用户：订单总览，按照月份返回订单条数，订单金额
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto partnerOrderLineChart(RequestOrderLineChart request, String token) {

        //1,先去公共服务类验证token
        String results = utilsService.checkPartner(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) && StringUtils.isNotBlank(request.getPartnerCode())) {

                String currentYear = timeUtil.currentYear();
                String month = timeUtil.currentMonth();

                if (StringUtils.isNotBlank(currentYear) && StringUtils.isNotBlank(month)) {

                    String firstMonth = currentYear + "-01";
                    String lastMonth = month;

                    //2，按照某个月的所有日期去查询对应的订单数量，订单总金额; 如果某一个月没有数据，需要补全日期对应补齐订单条数为0，订单总金额为0.00
                    List<String> dateList = timeUtil.getMonthBetween(firstMonth, lastMonth);
                    ArrayList<CalculateResultParamVo> voList = viewMapper.adminWithYearByMonth(firstMonth, lastMonth, request.getPartnerCode());

                    //返回
                    ResponseOrderLineChart response = new ResponseOrderLineChart();

                    //3，将从数据库查询到的按照每月的数据去处理一下并且转成mapList返回
                    List<Map<String, Object>> mapList = utilsService.dealOrderCountAndMoney(dateList, voList);

                    //4，合计：订单条数合计，订单金额合计（$）
                    List<CalculateResultParamVo> tolList = viewMapper.partnerOrderViewTotal(request.getPartnerCode(), currentYear);

                    //5,遍历合计中的订单条数合计，订单金额合计
                    if (null != tolList && tolList.size() > 0) {
                        for (CalculateResultParamVo data : tolList) {
                            response.setCountTotal(String.valueOf(data.getOrderCount()));
                            response.setMoneyTotal(String.valueOf(data.getOrderMoney()));
                        }
                    } else {
                        response.setCountTotal("0");
                        response.setMoneyTotal("0");
                    }
                    response.setDataByMonth(mapList);

                    log.info("【概览】普通用户：按月份显示订单总览返回：" + JSON.toJSONString(response));
                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(response);

                } else {
                    //当前月份没有拿到
                    return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PROGRAM_ERROR);
                }
            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /***
     * 普通企业：订单总览折线图，以及往期按月份数据
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto partnerOrderView(RequestOrderPastData request, String token) {
        //1,先去公共服务类验证token
        String results = utilsService.checkPartner(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) && StringUtils.isNotBlank(request.getPartnerCode())) {

                String currentYear = timeUtil.currentYear();

                if (StringUtils.isNotBlank(currentYear)) {

                    //按月分组查询到的订单数据，订单金额 ，如果数据库未查询到此订单会补全订单条数为0，订单总金额为0
                    List<CalculateResultParamVo> dataList = viewMapper.partnerOrderView(request.getPartnerCode(), currentYear);

                    List<String> countList = new ArrayList<>();
                    List<String> moneyList = new ArrayList<>();

                    for (CalculateResultParamVo data : dataList) {
                        moneyList.add(String.valueOf(data.getOrderMoney()));
                        countList.add(String.valueOf(data.getOrderCount()));
                    }

                    //合计：订单数据，订单金额
                    List<CalculateResultParamVo> tolList = viewMapper.partnerOrderViewTotal(request.getPartnerCode(), currentYear);

                    List<String> totalList = new ArrayList<>();

                    if (null != tolList && tolList.size() > 0) {
                        for (CalculateResultParamVo data : tolList) {
                            totalList.add(String.valueOf(data.getOrderCount()));
                            totalList.add(String.valueOf(data.getOrderMoney()));
                        }
                    } else {
                        totalList.add("0");
                        totalList.add("0");
                    }

                    ResponseOrderPastData responseList = new ResponseOrderPastData();
                    responseList.setOrderCount(countList);
                    responseList.setOrderMoney(moneyList);
                    responseList.setTotal(totalList);

                    log.info("【概览】订单往期按月份数据返回：" + JSON.toJSONString(responseList));

                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(responseList);

                } else {
                    //当前月份没有拿到
                    return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PROGRAM_ERROR);
                }

            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else

        {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }

    }

    /**
     * 普通企业：套餐销售排行榜Top20
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto partnerSalesRank(RequestSalesRank request, String token) {
        //1,先去公共服务类验证token
        String results = utilsService.checkPartner(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) &&
                    StringUtils.isNotBlank(request.getPartnerCode()) && null != request.getMonth()) {

                if (0 == request.getMonth() || 1 == request.getMonth()) {

                    //按套餐分组，按套餐售卖条数由多到少排序，limit20条
                    List<CalculateResultParamVo> salesRankList = null;

                    switch (request.getMonth()) {
                        case 1:
                            salesRankList = viewMapper.partnerSalesRank(request.getPartnerCode(), timeUtil.currentMonth());
                            break;
                        case 0:
                            salesRankList = viewMapper.partnerSalesRank(request.getPartnerCode(), timeUtil.lastMonth());
                            break;
                        default:
                            salesRankList = viewMapper.partnerSalesRank(request.getPartnerCode(), timeUtil.currentMonth());
                            break;
                    }

                    List<ResponseSalesRank> responseList = new ArrayList<ResponseSalesRank>();
                    ResponseSalesRank salesRank;

                    for (CalculateResultParamVo data : salesRankList) {
                        salesRank = new ResponseSalesRank();
                        salesRank.setServicePlanShowName(data.getServicePlanShowName());
                        salesRank.setOrderCount(String.valueOf(data.getOrderCount()));
                        salesRank.setOrderMoney(String.valueOf(data.getOrderMoney()));
                        responseList.add(salesRank);
                    }

                    log.info("【概览】订单往期按月份数据返回：" + JSON.toJSONString(responseList));
                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(responseList);

                } else {
                    // 上报的month值只能是0或者1，不允许是其他值
                    return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_MONTH_PARAM_ERROR);
                }
            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 管理员：周月订单，周月订单金额：顶部固定数据
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto adminFixedData(RequestAdminFixedData request, String token) {
        //1,先去公共服务类验证token
        String results = utilsService.checkAdmin(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion())) {

                //顶部订单固定数据：本月订单数，本月订单总额；本周订单数，本周订单总额：
                String currentMonth = timeUtil.currentMonth();
                String firstDayOfWeek = timeUtil.first();
                String endDayOfWeek = timeUtil.last();

                ResponseAdminFixedData response = new ResponseAdminFixedData();

                //1,先查本月的订单条数，本月订单总金额
                List<CalculateResultParamVo> monthOrderList = viewMapper.withMonthData("", currentMonth);

                if (null != monthOrderList && !monthOrderList.isEmpty()) {
                    for (CalculateResultParamVo vo : monthOrderList) {
                        if (null != vo.getOrderCount()) {
                            response.setCurMonthCount(String.valueOf(vo.getOrderCount()));
                        } else {
                            response.setCurMonthMoney("0");
                        }
                        if (null != vo.getOrderMoney()) {
                            response.setCurMonthMoney(String.valueOf(vo.getOrderMoney()));
                        } else {
                            response.setCurMonthMoney("0");
                        }
                    }

                } else {
                    response.setCurMonthCount("0");
                    response.setCurMonthMoney("0");
                }


                //2,再查本周的订单条数，本周订单总金额
                List<CalculateResultParamVo> weekOrderList = viewMapper.currentWeekData(firstDayOfWeek, endDayOfWeek);

                if (null != weekOrderList && !weekOrderList.isEmpty()) {
                    for (CalculateResultParamVo vo : weekOrderList) {
                        if (null != vo.getOrderCount()) {
                            response.setCurWeekCount(String.valueOf(vo.getOrderCount()));
                        } else {
                            response.setCurWeekCount("0");
                        }
                        if (null != vo.getOrderMoney()) {
                            response.setCurWeekMoney(String.valueOf(vo.getOrderMoney()));
                        } else {
                            response.setCurWeekMoney("0");
                        }
                    }
                } else {
                    response.setCurWeekCount("0");
                    response.setCurWeekMoney("0");
                }

                log.info("【概览】管理员：周月订单，周月订单金额：顶部固定数据返回：" + JSON.toJSONString(response));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(response);

            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 管理员：企业销售排行榜Top20
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto adminSalesRank(RequestAdminSalesRank request, String token) {
        //1,先去公共服务类验证token
        String results = utilsService.checkAdmin(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) && StringUtils.isNotBlank(request.getMark()) && StringUtils.isNotBlank(request.getDate())) {

                boolean b1 = ("0".equals(request.getMark()) && 7 == request.getDate().length()) || ("1".equals(request.getMark()) && 4 == request.getDate().length());

                if (!b1) {
                    // 上报mark或为0按月，但是date时间类型不是yyyy-MM;上报mark或为1按年，但是date时间类型不是yyyy;
                    return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_DATE_FORMAT_ERROR);
                }

                List<ResponseAdminSalesRank> responseList = new ArrayList<ResponseAdminSalesRank>();
                ResponseAdminSalesRank response = null;

                List<CalculateResultParamVo> salesRankList = null;

                if ("0".equals(request.getMark())) {
                    salesRankList = viewMapper.adminSalesRankByMonth(request.getDate());
                } else {
                    salesRankList = viewMapper.adminSalesRankByYear(request.getDate());
                }

                for (CalculateResultParamVo vo : salesRankList) {
                    response = new ResponseAdminSalesRank();
                    response.setPartnerName(vo.getPartnerName());
                    response.setOrderCount(String.valueOf(vo.getOrderCount()));
                    response.setOrderMoney(String.valueOf(vo.getOrderMoney()));
                    responseList.add(response);
                }

                log.info("【概览】管理员：企业销售排行榜Top20返回：" + JSON.toJSONString(responseList));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(responseList);

            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 管理员：按照月份，企业查询：
     * 1，当前选中的年份全年的订单总数，订单总额；
     * 2，当前选中的月份按天的订单总数，订单总额；
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto adminWithMonthData(RequestAdminMonthOrder request, String token) {
        //1,先去公共服务类验证token
        String results = utilsService.checkAdmin(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) &&
                    StringUtils.isNotBlank(request.getDate()) && null != request.getPartnerCode()) {

                ResponseAdminMonthOrder response = new ResponseAdminMonthOrder();
                String date = null;
                try {
                    date = request.getDate().substring(0, 4);
                } catch (Exception e) {

                }
                String dataDate = request.getDate() + "-01 11:11:11";
                String firstDay = timeUtil.getFirstDay(dataDate);
                String lastDay = null;
                //判断一下单月的情况，只允许展示到今天
                if (timeUtil.currentMonth().equals(request.getDate())) {
                    lastDay = timeUtil.currentDay();
                } else {
                    lastDay = timeUtil.getLastDay(dataDate);
                }

                //1，先算全年的订单数量，订单总金额；
                List<CalculateResultParamVo> yearOrderList = viewMapper.withYearData(request.getPartnerCode(), date);
                CalculateResultParamVo vo = utilsService.convertListToObject(yearOrderList);
                response.setYearOrderCount(String.valueOf(vo.getOrderCount()));
                response.setYearOrderMoney(String.valueOf(vo.getOrderMoney()));


                //2，按照某个月的所有日期去查询对应的订单数量，订单总金额; 如果某一个月没有数据，需要补全日期对应补齐订单条数为0，订单总金额为0.00
                List<String> dateList = timeUtil.getDateBetween(firstDay, lastDay);
                ArrayList<CalculateResultParamVo> voList = viewMapper.adminWithMonthByDay(firstDay, lastDay, request.getPartnerCode());

                //3，将从数据库查询到的按照每天的数据去处理一下并且转成mapList返回
                List<Map<String, Object>> mapList = utilsService.dealOrderCountAndMoney(dateList, voList);
                response.setDataByDay(mapList);

                log.info("【概览】管理员：按月订单总览返回：" + JSON.toJSONString(response));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(response);

            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 管理员：按照年份，企业查询：
     * 1，当前选中的年份全年的订单总数，订单总额；
     * 2，当前选中的年份按月的订单总数，订单总额；
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto adminWithYearData(RequestAdminYearOrder request, String token) {

        //1,先去公共服务类验证token
        String results = utilsService.checkAdmin(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) &&
                    StringUtils.isNotBlank(request.getDate()) && null != request.getPartnerCode()) {

                ResponseAdminYearOrder response = new ResponseAdminYearOrder();

                String firstMonth = request.getDate() + "-01";
                String lastMonth = null;
                //判断一下单月的情况，只允许展示到今天
                if (timeUtil.currentYear().equals(request.getDate())) {
                    lastMonth = timeUtil.currentMonth();
                } else {
                    lastMonth = request.getDate() + "-12";
                }

                //1，先算全年的订单数量，订单总金额；
                List<CalculateResultParamVo> yearOrderList = viewMapper.withYearData(request.getPartnerCode(), request.getDate());
                //处理并返回：全年的订单数量，订单总金额
                CalculateResultParamVo vo = utilsService.convertListToObject(yearOrderList);
                response.setYearOrderCount(String.valueOf(vo.getOrderCount()));
                response.setYearOrderMoney(String.valueOf(vo.getOrderMoney()));

                //2，按照某个月的所有日期去查询对应的订单数量，订单总金额; 如果某一个月没有数据，需要补全日期对应补齐订单条数为0，订单总金额为0.00
                List<String> dateList = timeUtil.getMonthBetween(firstMonth, lastMonth);
                ArrayList<CalculateResultParamVo> voList = viewMapper.adminWithYearByMonth(firstMonth, lastMonth, request.getPartnerCode());

                //3，将从数据库查询到的按照每月的数据去处理一下并且转成mapList返回
                List<Map<String, Object>> mapList = utilsService.dealOrderCountAndMoney(dateList, voList);
                response.setDataByMonth(mapList);

                log.info("【概览】管理员：按年订单总览返回：" + JSON.toJSONString(response));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(response);

            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 管理员：某企业默认情况：
     * <p>
     * 根据月份，年份查询：
     * 按照天显示，月份显示
     * 某个套餐，某一个规格在一定的时间段内（月或者年）对应的订单数
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto defaultOrderCount(RequestDefaultOrderCount request, String token) {

        //1,先去公共服务类验证token
        String results = utilsService.checkAdmin(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) &&
                    StringUtils.isNotBlank(request.getDate()) && StringUtils.isNotBlank(request.getPartnerCode()) && StringUtils.isNotBlank(request.getMark())) {

                boolean b1 = ("0".equals(request.getMark()) && 7 == request.getDate().length()) || ("1".equals(request.getMark()) && 4 == request.getDate().length());

                if (!b1) {
                    // 上报mark或为0按月，但是date时间类型不是yyyy-MM;上报mark或为1按年，但是date时间类型不是yyyy;
                    return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_DATE_FORMAT_ERROR);
                }

                ResponseDefaultOrderCount response = null;
                List<PartnerServicePlanList> codeList = new ArrayList<PartnerServicePlanList>();
                List<ContentLineChart> lineCharts = new ArrayList<ContentLineChart>();
                String name = "";

                //1，先去查询企业的套餐列表
                List<PartnerServicePlan> planList = viewMapper.partnerServicePlanList(request.getPartnerCode());

                //2，如果套餐列表是空的是需要直接返回告诉前端的
                if (null == planList || 0 >= planList.size() || planList.isEmpty()) {
                    //某个企业直接没有套餐列表，所以根本不需要查询
                    response = new ResponseDefaultOrderCount();
                    response.setServicePlanShowName(name);
                    response.setServicePlanList(codeList);
                    response.setLineChart(lineCharts);
                    log.info("【概览】管理员：当前企业无套餐列表，无订单返回：" + JSON.toJSONString(response));
                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(response);
                }

                PartnerServicePlanList plan = null;
                for (PartnerServicePlan p : planList) {
                    plan = new PartnerServicePlanList();
                    plan.setPartnerCode(p.getPartnerCode());
                    plan.setServicePlanCode(p.getServicePlanCode());
                    plan.setServicePlanShowName(p.getServicePlanShowName());
                    codeList.add(plan);
                }

                //2，默认时需要去订单系统拿到一个默认的套餐作为按照规格查询的依据：
                String servicePlanCode = viewMapper.queryServicePlanCode(request.getPartnerCode());
                //3，现在需要判断一下订单表里面是否存在卖过的订单，获取套餐的编码，如果返回为null证明根本没有卖过，直接给前端返回
                if (StringUtils.isBlank(servicePlanCode)) {
                    //某个企业在订单列表里面查不到servicePlanCode，说明没有卖过订单
                    response = new ResponseDefaultOrderCount();
                    response.setServicePlanShowName(name);
                    response.setServicePlanList(codeList);
                    response.setLineChart(lineCharts);
                    log.info("【概览】管理员：当前企业有套餐列表，无订单返回：" + JSON.toJSONString(response));
                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(response);
                }

                List<String> dateList = null;
                String first = null;
                String last = null;

                //这边开始按照不同的mark值去组织first和last
                if ("0".equals(request.getMark())) {
                    //3，根据请求的月份日期去判断出我们应该在折线图上反应哪些日期对应的数据
                    String dataDate = request.getDate() + "-01 11:11:11";
                    first = timeUtil.getFirstDay(dataDate);
                    //4，判断一下单月的情况，只允许展示到今天，lastDay就为今天
                    if (timeUtil.currentMonth().equals(request.getDate())) {
                        last = timeUtil.currentDay();
                    } else {
                        last = timeUtil.getLastDay(dataDate);
                    }

                    //5,按照输入日期去获得应该被查询的日期list列表
                    dateList = timeUtil.getDateBetween(first, last);
                } else {
                    //3，根据请求的年份去判断出我们应该在折线图上反应哪些月份对应的数据
                    first = request.getDate() + "-01";
                    //判断一下单月的情况，只允许展示到本月
                    if (timeUtil.currentYear().equals(request.getDate())) {
                        last = timeUtil.currentMonth();
                    } else {
                        last = request.getDate() + "-12";
                    }
                    //5,按照输入日期去获得应该被查询的月份list列表
                    dateList = timeUtil.getMonthBetween(first, last);
                }

                //6，拿着套餐编码去查套餐规格：
                List<PartnerServicePlanSpecPrice> specificationsList = viewMapper.querySpecifications(request.getPartnerCode(), servicePlanCode);

                //7，如果规格列表是空的是需要直接返回告诉前端的
                if (null == specificationsList || 0 >= specificationsList.size() || specificationsList.isEmpty()) {
                    //这种情况应该是极端的情况
                    response = new ResponseDefaultOrderCount();
                    response.setServicePlanShowName(name);
                    response.setServicePlanList(codeList);
                    response.setLineChart(lineCharts);
                    log.info("【概览】管理员：当前企业有套餐列表，有订单，但是规格列表查询有误返回：" + JSON.toJSONString(response));
                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(response);
                }

                ContentLineChart lineChart = null;
                for (PartnerServicePlanSpecPrice specPrice : specificationsList) {

                    String unit = utilsService.getUnit(specPrice.getPackageType());
                    name = specPrice.getServicePlanShowName();
                    ArrayList<CalculateResultParamVo> voList = null;

                    if ("0".equals(request.getMark())) {
                        //7,将查询到的套餐的规格按照for循环输出，去查询此规格套餐在某段时间内按照天来算，每天的订单数量
                        voList = viewMapper.orderCountByDay(first, last, request.getPartnerCode(), specPrice.getServicePlanCode(), specPrice.getSpecifications());
                    } else {
                        //7,将查询到的套餐的规格按照for循环输出，去查询此规格套餐在某段时间内按照天来算，每天的订单数量
                        voList = viewMapper.orderCountByMonth(first, last, request.getPartnerCode(), specPrice.getServicePlanCode(), specPrice.getSpecifications());
                    }

                    //8，将从数据库查询到的数据放到map里面处理一下：按照日期对应，如果日期对应数据为空就补0
                    List<Map<String, Object>> mapList = utilsService.dealOrderCount(dateList, voList);
                    log.info(specPrice.getSpecifications() + unit + "：mapList:" + mapList);

                    //9，将mapList中所有key为orderCount的value全部取出来，然后赋给String[]数组里面
                    String[] data = new String[mapList.size()];
                    for (int i = 0; i < mapList.size(); i++) {
                        String res = mapList.get(i).get("orderCount") + "";
                        //数组赋值了。
                        data[i] = res;
                    }
                    //10，将String[]数组赋值给折线元素data[]
                    lineChart = new ContentLineChart();
                    lineChart.setData(data);
                    lineChart.setType("line");
                    lineChart.setName(specPrice.getSpecifications() + unit);
                    lineCharts.add(lineChart);
                }
                //11,成功的情况拼接返回
                response = new ResponseDefaultOrderCount();
                response.setServicePlanShowName(name);
                response.setServicePlanList(codeList);
                response.setLineChart(lineCharts);
                log.info("【概览】管理员：默认请求按规格查询按天或者按月展示的订单数返回：" + JSON.toJSONString(response));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(response);

            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 管理员：某企业实际套餐情况：
     * <p>
     * 根据月份，年份查询：
     * 按照天显示，月份显示
     * 某个套餐，某一个规格在一定的时间段内（月或者年）对应的订单数
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto askOrderCount(RequestAskOrderCount request, String token) {

        //1,先去公共服务类验证token
        String results = utilsService.checkAdmin(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) &&
                    StringUtils.isNotBlank(request.getDate()) && StringUtils.isNotBlank(request.getPartnerCode()) && StringUtils.isNotBlank(request.getMark()) && StringUtils.isNotBlank(request.getServicePlanCode())) {

                boolean b1 = ("0".equals(request.getMark()) && 7 == request.getDate().length()) || ("1".equals(request.getMark()) && 4 == request.getDate().length());

                if (!b1) {
                    // 上报mark或为0按月，但是date时间类型不是yyyy-MM;上报mark或为1按年，但是date时间类型不是yyyy;
                    return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_DATE_FORMAT_ERROR);
                }

                ResponseAskOrderCount response = null;
                List<ContentLineChart> lineCharts = new ArrayList<ContentLineChart>();
                String name = "";
                List<String> dateList = null;
                String first = null;
                String last = null;

                //这边开始按照不同的mark值去组织first和last
                if ("0".equals(request.getMark())) {
                    //3，根据请求的月份日期去判断出我们应该在折线图上反应哪些日期对应的数据
                    String dataDate = request.getDate() + "-01 11:11:11";
                    first = timeUtil.getFirstDay(dataDate);
                    //4，判断一下单月的情况，只允许展示到今天，lastDay就为今天
                    last = utilsService.findLastDate(request.getDate(), "0");
                    //5,按照输入日期去获得应该被查询的日期list列表
                    dateList = utilsService.findDateList(request.getMark(), request.getDate());
                } else {
                    //3，根据请求的年份去判断出我们应该在折线图上反应哪些月份对应的数据
                    first = request.getDate() + "-01";
                    //4,判断一下单月的情况，只允许展示到本月
                    last = utilsService.findLastDate(request.getDate(), "1");
                    //5,按照输入日期去获得应该被查询的月份list列表
                    dateList = utilsService.findDateList(request.getMark(), request.getDate());
                }

                //6，拿着套餐编码去查套餐规格：
                List<PartnerServicePlanSpecPrice> specificationsList = viewMapper.querySpecifications(request.getPartnerCode(), request.getServicePlanCode());

                //7，如果规格列表是空的是需要直接返回告诉前端的
                if (null == specificationsList || 0 >= specificationsList.size() || specificationsList.isEmpty()) {
                    //这种情况应该是极端的情况
                    response = new ResponseAskOrderCount();
                    response.setServicePlanShowName(name);
                    response.setLineChart(lineCharts);
                    log.info("【概览】管理员：当前企业有套餐列表，有订单，但是规格列表查询有误返回：" + JSON.toJSONString(response));
                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(response);
                }

                ContentLineChart lineChart = null;
                for (PartnerServicePlanSpecPrice specPrice : specificationsList) {

                    String unit = utilsService.getUnit(specPrice.getPackageType());
                    name = specPrice.getServicePlanShowName();

                    ArrayList<CalculateResultParamVo> voList = null;

                    if ("1".equals(request.getMark())) {
                        //7,将查询到的套餐的规格按照for循环输出，去查询此规格套餐在某段时间内按照天来算，每天的订单数量
                        voList = viewMapper.orderCountByMonth(first, last, request.getPartnerCode(), specPrice.getServicePlanCode(), specPrice.getSpecifications());
                    } else {
                        //7,将查询到的套餐的规格按照for循环输出，去查询此规格套餐在某段时间内按照天来算，每天的订单数量
                        voList = viewMapper.orderCountByDay(first, last, request.getPartnerCode(), specPrice.getServicePlanCode(), specPrice.getSpecifications());
                    }

                    //8，将从数据库查询到的数据放到map里面处理一下：按照日期对应，如果日期对应数据为空就补0
                    List<Map<String, Object>> mapList = utilsService.dealOrderCount(dateList, voList);
                    log.info(specPrice.getSpecifications() + unit + "：mapList:" + mapList);

                    //9，将mapList中所有key为orderCount的value全部取出来，然后赋给String[]数组里面
                    String[] data = new String[mapList.size()];
                    for (int i = 0; i < mapList.size(); i++) {
                        String res = mapList.get(i).get("orderCount") + "";
                        //数组赋值了。
                        data[i] = res;
                    }
                    //10，将String[]数组赋值给折线元素data[]
                    lineChart = new ContentLineChart();
                    lineChart.setData(data);
                    lineChart.setType("line");
                    lineChart.setName(specPrice.getSpecifications() + unit);
                    lineCharts.add(lineChart);
                }
                //11,成功的情况拼接返回数据
                response = new ResponseAskOrderCount();
                response.setServicePlanShowName(name);
                response.setLineChart(lineCharts);

                log.info("【概览】管理员：实际请求按规格查询按天或者按月展示的订单数返回：" + JSON.toJSONString(response));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(response);


            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }

    /**
     * 管理员：某企业实际请求：
     * <p>
     * 根据月份，年份查询：
     * 按照天显示，月份显示
     * 某个套餐，某一个规格在一定的时间段内（月或者年）对应的订单总金额
     *
     * @param request
     * @param token
     * @return
     */
    @Override
    public ResultDataDto askOrderMoney(RequestAskOrderMoney request, String token) {
        //1,先去公共服务类验证token
        String results = utilsService.checkAdmin(token);

        if (StringUtils.isNotBlank(results) && StringOutputConstant.CODE_SUCCESS.equals(results)) {

            if (StringUtils.isNotBlank(request.getTradeType()) && StringUtils.isNotBlank(request.getLang()) && StringUtils.isNotBlank(request.getVersion()) &&
                    StringUtils.isNotBlank(request.getDate()) && StringUtils.isNotBlank(request.getPartnerCode()) && StringUtils.isNotBlank(request.getMark()) && StringUtils.isNotBlank(request.getServicePlanCode())) {

                boolean b1 = ("0".equals(request.getMark()) && 7 == request.getDate().length()) || ("1".equals(request.getMark()) && 4 == request.getDate().length());

                if (!b1) {
                    // 上报mark或为0按月，但是date时间类型不是yyyy-MM;上报mark或为1按年，但是date时间类型不是yyyy;
                    return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_DATE_FORMAT_ERROR);
                }

                ResponseAskOrderMoney response = null;
                List<ContentLineChart> lineCharts = new ArrayList<ContentLineChart>();
                String name = "";
                List<String> dateList = null;
                String first = null;
                String last = null;

                //这边开始按照不同的mark值去组织first和last
                if ("1".equals(request.getMark())) {
                    //3，根据请求的年份去判断出我们应该在折线图上反应哪些月份对应的数据
                    first = request.getDate() + "-01";
                    //4,判断一下单月的情况，只允许展示到本月
                    last = utilsService.findLastDate(request.getDate(), "1");
                    //5,按照输入日期去获得应该被查询的月份list列表
                    dateList = utilsService.findDateList(request.getMark(), request.getDate());
                } else {
                    //3，根据请求的月份日期去判断出我们应该在折线图上反应哪些日期对应的数据
                    String dataDate = request.getDate() + "-01 11:11:11";
                    first = timeUtil.getFirstDay(dataDate);
                    //4，判断一下单月的情况，只允许展示到今天，lastDay就为今天
                    last = utilsService.findLastDate(request.getDate(), "0");
                    //5,按照输入日期去获得应该被查询的日期list列表
                    dateList = utilsService.findDateList(request.getMark(), request.getDate());
                }

                //6，拿着套餐编码去查套餐规格：
                List<PartnerServicePlanSpecPrice> specificationsList = viewMapper.querySpecifications(request.getPartnerCode(), request.getServicePlanCode());

                //7，如果规格列表是空的是需要直接返回告诉前端的
                if (null == specificationsList || 0 >= specificationsList.size() || specificationsList.isEmpty()) {
                    //这种情况应该是极端的情况
                    response = new ResponseAskOrderMoney();
                    response.setServicePlanShowName(name);
                    response.setLineChart(lineCharts);
                    log.info("【概览】管理员：按规格查询订单总金额时，规格列表为空返回：" + JSON.toJSONString(response));
                    //给前端统一返回
                    return ResultDataDto.addOperationSuccess().setData(response);
                }

                ContentLineChart lineChart = null;
                for (PartnerServicePlanSpecPrice specPrice : specificationsList) {

                    String unit = utilsService.getUnit(specPrice.getPackageType());
                    name = specPrice.getServicePlanShowName();

                    ArrayList<CalculateResultParamVo> voList = null;

                    if ("1".equals(request.getMark())) {
                        //7,将查询到的套餐的规格按照for循环输出，去查询此规格套餐在某段时间内按照月来算，每月的订单数量
                        voList = viewMapper.orderMoneyByMonth(first, last, request.getPartnerCode(), specPrice.getServicePlanCode(), specPrice.getSpecifications());
                    } else {
                        //7,将查询到的套餐的规格按照for循环输出，去查询此规格套餐在某段时间内按照天来算，每天的订单数量
                        voList = viewMapper.orderMoneyByDay(first, last, request.getPartnerCode(), specPrice.getServicePlanCode(), specPrice.getSpecifications());
                    }

                    //8，将从数据库查询到的数据放到map里面处理一下：按照日期对应，如果日期对应数据为空就补0
                    List<Map<String, Object>> mapList = utilsService.dealOrderMoney(dateList, voList);
                    log.info(specPrice.getSpecifications() + unit + "：mapList:" + mapList);

                    //9，将mapList中所有key为orderCount的value全部取出来，然后赋给String[]数组里面
                    String[] data = new String[mapList.size()];
                    for (int i = 0; i < mapList.size(); i++) {
                        String res = mapList.get(i).get("orderMoney") + "";
                        //数组赋值了。
                        data[i] = res;
                    }
                    //10，将String[]数组赋值给折线元素data[]
                    lineChart = new ContentLineChart();
                    lineChart.setData(data);
                    lineChart.setType("line");
                    lineChart.setName(specPrice.getSpecifications() + unit);
                    lineCharts.add(lineChart);
                }
                //11,拼接返回数据
                response = new ResponseAskOrderMoney();
                response.setServicePlanShowName(name);
                response.setLineChart(lineCharts);

                log.info("【概览】管理员：实际请求按规格查询按天或者按月展示的订单总金额返回：" + JSON.toJSONString(response));
                //给前端统一返回
                return ResultDataDto.addOperationSuccess().setData(response);


            } else {
                // 上报的存在不允许为空的参数
                return ResultDataDto.addOperationFailure(StringOutputConstant.CODE_PARAM_ERROR);
            }
        } else {
            // 验证token：要么登录相关问题，要么权限有问题
            return ResultDataDto.addOperationFailure(results);
        }
    }


}
